<?php

/**
 * Gestionnaire du systeme de Template
 *
 * @category   McCube
 * @package    Template
 * @author     Leiha Sellier <leiha.sellier@gmail.com>
 * @license    http://creativecommons.org/licenses/by/3.0/  CC BY 3.0
 * @link       http://code.google.com/p/mechanics-cubes/
 */
class McCube_Template{

    protected static $_debug  = false;
    protected static $_blocks = array();
    protected static $_config = array();

    /** */
    public static function setBlock($name, $content){
        self::$_blocks[$name] = $content;
    }

    /** */
    public static function getBlock($name, $defaultValue){
        if(!isset(self::$blocks[$name])){
            if(self::$debug && !$defaultValue){
                if('strict' === self::$debug)
                    throw new McCube_Exception_Template('Block', 404, array(
                        'name'=> $name
                    ));

                return '!-[ #BLOCK '.$name.' ]-!';
            }
            return $defaultValue;
        }
        return self::$blocks[$name];
    }

    /** */
    public static function init(array $config=array()){
        self::$_config = $config;
        if(!isset($config['extension']))
            self::$_config['extension'] = '.tpl';

        if(isset($config['debug']) && self::$_config['debug'])
            self::$_debug = isset($config['debug_strict'])
                && $config['debug_strict']
                    ? 'strict'
                    : true
            ;
    }

    /* -------------------------------------------------- */

    public    $bundle     = null;
    protected $_cachePath = '';
    protected $_viewsPath = '';

    /** */
    public function __construct($bundle){
        $this->bundle = $bundle;
    }

    /** */
    public function setPaths($views, $cache=''){
        $this->_viewsPath = $views;
        $this->_cachePath = $cache;
        return $this;
    }

    /** */
    public function fetchFile($filename, $varsForBuffer=array()){
        return $this->fetchFileByParser($filename, $varsForBuffer);
    }

    /** */
	public function fetchFileByBuffer($filename, $varsForBuffer=array()){
        return $this->getBuffer()->bufferFile(
              $this->_getPathView($filename, true, self::$_config['cache'])
            , $varsForBuffer
        );
    }

    /** */
	public function fetchFileByParser($filename, $varsForBuffer=array()){

	    $content = $this->getParser()->parseFile(
              $this->_getPathView($filename)
            , $varsForBuffer
        );
        $content = $this->merge($content, $varsForBuffer);

        if(self::$_config['cache'])
            $this->cacheContent($filename, $content);

        return $this->getBuffer()->bufferString($content, $varsForBuffer);
    }

    public function capture($string, $original=false){
        if(!preg_match_all(
            '~'
            .'<!- START EXECUTION ([0-9]+) -->'
            .'(.*)'
            .'<!- END EXECUTION \1 -->'
            .'~s'
            ,$string
            ,$matches
            ,PREG_SET_ORDER
        ))
            return;

        foreach($matches as $match)
            $_[$match[1]] = $match[$original ? 0 : 2];

        return $_;
    }

    /** */
	public function merge($content, $varsForBuffer=array()){
        if(!$matches = $this->capture($content, true))
            return $content;

        return str_replace(
              $matches
            , $this->capture(
                  $this->getBuffer()->bufferString($content, $varsForBuffer)
            )
            , $content
        );
    }

    /** */
	public function getBuffer(){
        return new MCCube_Template_Buffer();
    }

    /** */
	public function getParser(){
        return new MCCube_Template_Parser($this);
    }

    protected function _getPathView($name, $required=true, $cache=false, $extension='.tpl'){
        return $this->bundle->getPathView($name, $required, $cache, $extension);
    }

    /** */
    public function cacheContent($filename, $content){
        $filename = $this->_getPathView($filename, false, true);
        $basedir  = dirname($filename);
        if(!is_dir($basedir))
            mkdir($basedir,'0777', true);

        file_put_contents($filename, trim($content));
    }
}